#include "Resource.h"
#include "Game.h"
#include "Item.h"
#include "Tool.h"
#include "ObjectDatabase.h"
#include "StringLib.h"
#include "Renderer.h"
#include "Util.h"
#include "Ingredient.h"

Resource::Resource(ResourceType type, int numResources) : Obstacle(GT_OB_RESOURCE) {
	m_types[TH_RESOURCE_TYPE] = type;
	m_blocking = true;
	m_numResources = numResources;
	const ResourceInfo& info = g_objectDatabase->getResourceInfo(type);
	m_bonusFlag = info.bonusflag;
	m_quality = info.quality;
	m_health = m_currentHealth = info.health;
	m_ingredientType = info.ingredient;
	m_types[TH_RESOURCE_FAMILY] = info.family;
}

Resource::Resource(std::ifstream& file) : Obstacle(GT_OB_RESOURCE, file) {
	int* tokens = Util::intSplit(file);
	m_types[TH_RESOURCE_TYPE] = tokens[0];
	m_numResources = tokens[1];
	m_currentHealth = tokens[2];
	m_blocking = true;
	const ResourceInfo& info = g_objectDatabase->getResourceInfo(ResourceType(tokens[0]));
	m_bonusFlag = info.bonusflag;
	m_quality = info.quality;
	m_ingredientType = info.ingredient;
	m_health = info.health;
	m_types[TH_RESOURCE_FAMILY] = info.family;
	delete[] tokens;
}

Resource::~Resource() {
}

void Resource::save(std::ofstream& file) const {
	file << getType(TH_GENERIC_TYPE) << "\n";
	Obstacle::save(file);
	file << getType(TH_RESOURCE_TYPE) << " " << m_numResources << " " << m_currentHealth << "\n";
}

void Resource::render(float x, float y) {
	g_renderer->render(*this, x, y);
}

void Resource::logDetails(TextLog& log) const {
	Obstacle::logDetails(log);
	log.addBlankLine();
	log.addLine(g_stringLib->getTextString(ST_RESOURCE_NUM_LEFT, Util::intToString(m_numResources).c_str()));
	log.addLine(g_stringLib->getTextString(ST_RESOURCE_HARDNESS, Util::intToString(m_quality).c_str()));
	log.addLine(g_stringLib->getTextString(ST_RESOURCE_HEALTH, Util::intToString(m_currentHealth).c_str()));
}

std::list<Item*>* Resource::handleStrike() {
	std::list<Item*>* items = new std::list<Item*>();
	if(m_currentHealth <= 0) {
		while(m_currentHealth <= 0 && m_numResources > 0) {
			m_currentHealth += m_health;
			m_numResources--;
			Item* item;
			if(m_bonusFlag != -1 && one_in(10)) {
				item = new Ingredient(IngredientType(m_bonusFlag));
				g_textLog->addLine(g_stringLib->getTextString(ST_RESOURCE_GATHER_RARE, item->getColoredName().c_str()));
			} else {
				item = new Ingredient(IngredientType(m_ingredientType));
				g_textLog->addLine(g_stringLib->getTextString(ST_RESOURCE_GATHER, item->getColoredName().c_str()));
			}
			items->push_back(item);
		}
	} else {
		g_textLog->addLine(g_stringLib->getTextString(ST_RESOURCE_GATHER_NONE));
	}
	return items;
}

std::list<Item*>* Resource::gather(Tool* tool) {
	std::list<Item*>* items = NULL;
	g_textLog->addLine(g_stringLib->getTextString(ST_RESOURCE_GATHER_ATTEMPT, getColoredBasicName().c_str(), tool->getColoredBasicName().c_str()));
	if(int(tool->getPrefix()) >= m_quality) {
		m_currentHealth -= tool->getPower();
		items = handleStrike();
	} else {
		switch(getType(TH_RESOURCE_FAMILY)) {
		case RF_PLANT: {
			m_currentHealth -= tool->getPower();
			bool failed = one_in(3);
			if(m_currentHealth > 0 && failed)
				m_currentHealth = 0;

			if(failed) {
				m_currentHealth = m_health;
				m_numResources--;
				switch(getType(TH_RESOURCE_FAMILY)) {
				case RF_PLANT:
					g_textLog->addLine(g_stringLib->getTextString(ST_RESOURCE_DAMAGE) + " " + g_stringLib->getTextString(ST_RESOURCE_DAMAGE_PLANT, g_stringLib->getObjectString(TH_INGREDIENT_TYPE, m_ingredientType).c_str()));
					break;
				}
			} else {
				handleStrike();
			}
			break;
		}
		default:
			g_textLog->addLine(g_stringLib->getTextString(ST_RESOURCE_DAMAGE));
			break;
		}
	}

	return items;
}

bool Resource::destroy(int num) {
	m_numResources -= num;
	return m_numResources <= 0;
}

bool Resource::isRightTool(const Tool& tool) const {
	switch(getType(TH_RESOURCE_FAMILY)) {
	case RF_PLANT:
		return tool.getType(TH_TOOL_TYPE) == TT_PLANT;
	case RF_METAL:
		return tool.getType(TH_TOOL_TYPE) == TT_METAL;
	}
	return false;
}
